package com.xindacloud.sms.portal.controller;

import com.google.gson.Gson;
import com.xindacloud.sms.portal.dto.SmsReportDTO;
import com.xindacloud.sms.portal.exception.ServiceException;
import com.xindacloud.sms.portal.properties.EndpointProperties;
import com.xindacloud.sms.portal.utils.CsvExportUtil;
import com.xindacloud.sms.portal.utils.UnionResultHelp;
import com.xindacloud.sms.portal.utils.UserSessionHelp;
import com.xindacloud.sms.portal.vo.SmsDownloadReportLogVO;
import com.xindacloud.sms.portal.vo.SmsReportVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.*;

@Api(tags = "短信报告接口模块")
@Slf4j
@RestController
@RequestMapping(value = "/api/v1/portal/sms/report")
public class ReportController {

    final EndpointProperties endpointProperties;

    @Autowired
    public ReportController(EndpointProperties endpointProperties) {
        this.endpointProperties = endpointProperties;
    }

    @ApiOperation(value = "下载短信报告", response = SmsReportVO.class)
    @PostMapping(value = "/download", produces = MediaType.APPLICATION_JSON_VALUE)
    public void downloadReport(@ApiParam(name = "smsReportDTO", value = "查询短信报告", required = true)
                               @RequestBody SmsReportDTO smsReportDTO,
                               HttpServletRequest request, HttpServletResponse response) {

        String url = endpointProperties.getAdapterGateway().concat(endpointProperties.getAdapterReportPath());
        final UnionResultHelp block = WebClient
                .create(url)
                .post()
                .accept(MediaType.APPLICATION_JSON)
                .headers(UserSessionHelp.getHttpHeadersConsumer(request))
                .body(Mono.just(smsReportDTO), SmsReportDTO.class)
                .retrieve()
                .onStatus(HttpStatus::is4xxClientError, clientResponse ->
                        Mono.error(new ServiceException("获取短信报告异常.", clientResponse.statusCode().value()))
                )
                .onStatus(HttpStatus::is5xxServerError, clientResponse ->
                        Mono.error(new ServiceException("获取短信报告异常.", clientResponse.statusCode().value()))
                )
                .bodyToMono(new ParameterizedTypeReference<UnionResultHelp>() {
                })
                .block();

        try {
            final List<Object> data = (List<Object>) block.getData();
            if (Objects.nonNull(data)) {
                final Gson gson = new Gson();
                // 构造导出数据结构
                String titles =smsReportDTO.getReportColumns().concat(",reason,messageTimestamp");  // 设置表头
                String keys = titles;  // 设置每列字段

                // 构造导出数据
                List<Map<String, Object>> dataList = new ArrayList<>();
                Map<String, Object> map;
                //countryName,prefix,networkName,status,recipient,price,messageBody
                List<String> titlesList = Arrays.asList(titles.split(","));
                for (Object object : data) {
                    Map<String, Object> resultMap = (Map<String, Object>) object;
                    SmsReportVO reportVO = gson.fromJson(gson.toJson(resultMap), SmsReportVO.class);
                    map = new HashMap<>();
                    map.put("messageId", reportVO.getMessageId());
                    if (titlesList.contains("clientName")) {
                        map.put("clientName", reportVO.getClientName());
                    }
                    if (titlesList.contains("sender")) {
                        map.put("sender", reportVO.getSender());
                    }
                    if (titlesList.contains("countryName")) {
                        map.put("countryName", reportVO.getCountryName());
                    }
                    if (titlesList.contains("prefix")) {
                        map.put("prefix", reportVO.getPrefix());
                    }
                    if (titlesList.contains("networkName")) {
                        map.put("networkName", reportVO.getNetworkName());
                    }
                    if (titlesList.contains("status")) {
                        map.put("status", reportVO.getFinalStatus());
                    }
                    if (titlesList.contains("recipient")) {
                        map.put("recipient", reportVO.getSendTo());
                    }
                    if (titlesList.contains("price")) {
                        map.put("price", String.format("%.4f", reportVO.getFree()));
                    }
                    if (titlesList.contains("messageBody")) {
                        map.put("messageBody", reportVO.getMessageBody());
                    }

                    map.put("reason", reportVO.getReason());
                    map.put("messageTimestamp", reportVO.getMessageTimestamp());
                    dataList.add(map);
                }

                // 设置导出文件前缀
                String fName = "report-";
                // 文件导出
                OutputStream os = response.getOutputStream();
                CsvExportUtil.responseSetProperties(fName, "csv", response);
                CsvExportUtil.doExport(dataList, titles, keys, os);

            }
        } catch (Exception e) {
            log.error("导出异常:{}", e.getMessage(), e);
        }
    }


    @ApiOperation(value = "查询短信报告日志", response = SmsDownloadReportLogVO.class)
    @PostMapping(value = "/logs", produces = MediaType.APPLICATION_JSON_VALUE)
    public UnionResultHelp queryReportLog(HttpServletRequest request) {

        String url = endpointProperties.getAdapterGateway().concat(endpointProperties.getAdapterReportLogPath());
        return WebClient
                .create(url)
                .post()
                .accept(MediaType.APPLICATION_JSON)
                .headers(UserSessionHelp.getHttpHeadersConsumer(request))
                .retrieve()
                .onStatus(HttpStatus::is4xxClientError, clientResponse ->
                        Mono.error(new ServiceException("获取短信报告异常.", clientResponse.statusCode().value()))
                )
                .onStatus(HttpStatus::is5xxServerError, clientResponse ->
                        Mono.error(new ServiceException("获取短信报告异常.", clientResponse.statusCode().value()))
                )
                .bodyToMono(new ParameterizedTypeReference<UnionResultHelp>() {
                })
                .block();
    }

}
